#include "BufferBitmap.h"

#include "M5ImgDec.h"

#define FREEEX(buf)	{ if (buf) free(buf); buf = NULL; }

#define RGB565to888ValueR(rgb555)	((BYTE)((rgb555 >> 8) & 0xF8))
#define RGB565to888ValueG(rgb555)	((BYTE)((rgb555 >> 3) & 0xFC))
#define RGB565to888ValueB(rgb555)	((BYTE)((rgb555 << 3) & 0xF8))
#define RGB888to565(r,g,b)			((WORD)(((((WORD)r)<<8)&0xF800)|((((WORD)g)<<3)&0x7E0)|(((WORD)b)>>3)))

CBufferBitmap::CBufferBitmap(void)
: m_bit(NULL)
, m_alpha(NULL)
, m_width(0)
, m_height(0)
{
}

CBufferBitmap::~CBufferBitmap(void)
{
	Reset();
}

bool CBufferBitmap::Init(int width, int height)
{
	bool ret = false;

	if (width > 0 && height > 0)
	{
		m_width = width;
		m_height = height;
	}

	return ret;
}

void CBufferBitmap::Reset()
{
	FREEEX(m_bit);
	FREEEX(m_alpha);

	m_width = 0;
	m_height = 0;
}

bool CBufferBitmap::SetImage(const char * szFilePath)
{
	bool ret = false;

	if (szFilePath && strlen(szFilePath) > 0)
	{
		CM5ImgDec dec;
		if (dec.Decode(szFilePath))
		{
			m_width = dec.GetWidth();
			m_height = dec.GetHeight();
			if (m_width > 0 && m_height > 0)
			{
				FREEEX(m_bit);
				FREEEX(m_alpha);

				m_bit = (byte *)malloc((m_width * 6 + 4) * m_height);
				if (m_bit && dec.GetFrame1(m_bit, 0, IMG_MOD_24BPP))
				{
					ret = true;

					if (dec.HasAlpha(0))
					{
						m_alpha = (byte *)malloc(m_width * m_height);
						if (m_alpha)
						{
							if (!dec.GetFrameAlpha(m_alpha, 0))
							{
								FREEEX(m_alpha);
							}
						}
					}
				}
				else
				{
					FREEEX(m_alpha);
				}
			}
			else
			{
				m_width = 0;
				m_height = 0;
			}
		}
	}

	return ret;
}

bool CBufferBitmap::SetBitmapData(int width, int height, byte * bit, int bit_len, byte * alpha, int alpha_len)
{
	return false;
}

bool CBufferBitmap::DrawTo(CBufferBitmap & bitmap, int x, int y)
{
	return false;
}

HBITMAP CBufferBitmap::ExportBitmap()
{
	HBITMAP bitmap = NULL;

	if (m_width > 0 && m_height > 0 && m_bit)
	{
		int src_pitch = 0, dst_pitch = 0 ;
		int src_jump = 0, dst_jump = 0 ;
		int i, j ; 
		int x = 0, y = 0, w = m_width, h = m_height;
		byte * bit = (byte *)malloc(_msize(m_bit));

		if (bit)
		{
			src_pitch = (w * 3) % 4;
			dst_pitch = w % 4;
			if (src_pitch)
				src_pitch = 4 - src_pitch;
			if (dst_pitch)
				dst_pitch = 4 - dst_pitch;
			src_jump = w * 3 + dst_pitch;
			dst_jump = w + dst_pitch;
			u_short * src = (u_short *)m_bit;
			u_short * dst = (u_short *)bit ; 
			dst += (y * dst_jump + x);
			for(i = 0 ; i < h ; i++) {
				for (j = 0; j < w; j++)
				{
					WORD rbg565 = RGB888to565(src[j*3+2], src[j*3+1], src[j*3]);

					memcpy(dst + j, (void *)&rbg565, 2);
				}
				src += src_jump;
				dst += dst_jump;
			}

			bitmap = CreateBitmap(m_width, m_height, 1, 16, bit);

			free(bit);
		}
	}

	return bitmap;
}